Triggers and Animators
Trigger:Triggers和Animators
触发器提供了使用Fuse创建动画的声明式方法。最基本的,触发器表示响应于用户和/或程序输入而触发的事件。Triggers可以包含Animators和Actions,用于动画和操作元素以及与JavaScript交互。
Trigger是生活在Node或UI Element上的行为,监听事件并执行动画和动作作为响应。
例如,这里是一个面板与WhilePressed触发器,使面板旋转90度与弹跳动画。
| 
 | 
##视频介绍触发器和动画
[YOUTUBE bT1npBvXEzw]
静止状态和偏差
UX标记元素的默认布局和配置称为休眠状态。
触发器定义与该静止状态的偏差。
每个触发器知道如何“取消应用”其自己的动画返回到休息状态,即使中间动画中断。
这是伟大的,因为它意味着动画完全从你的程序的逻辑状态分离,大大降低了处理组合动画的复杂性
多个设备,屏幕尺寸,真实数据和真实用户输入。
BackwardAnimation:单独的向前和向后动画
一些高级触发器动画允许单独的向前和向后动画。
要做到这一点,将后向动画放在一个TriggerAnimation里,绑定它做父动(向前)动画上的BackwardAnimation绑定。下面的例子使用BackwardAnimation在动画回到空闲状态时用不同的缓动动画。
| 
 | 
注意:“BackwardAnimation”中的动画自动右对齐。
动画师
动画师用于指定在触发触发器时要触发元素的动画。
有三对属性对于控制动画的确切结果很重要。
Duration/ DurationBack
当动画向前和向后动画时,动画可以具有不同的行为。当触发器被激活时,动画被称为向前播放。当触发器被禁用时,动画向后播放。持续时间用于设置动画的持续时间。可以使用DurationBack属性为后向动画设置不同的持续时间。
当触发器中有多个animator时,触发器的总持续时间将是动画器中最长的持续时间。
在以下示例中,WhileTrue触发器的总持续时间将为3秒。如果我们想让动画一个接一个地发生,我们可以使用延迟。
| 
 | 
Delay/ DelayBack
设置“Delay”属性会导致实际动画被延迟该秒数。DelayBack用于对后向动画设置不同的延迟。动画的总持续时间变为延迟+持续时间。以下更改动画师的总持续时间为7秒。它在激活后等待5秒钟,然后在2秒内对其目标元素进行动画处理。
| 
 | 
Easing/ EasingBack
保险丝带有一组标准的预定义缓动曲线。缓动曲线用于控制动画随时间推移的过程。默认缓动设置为“线性”。使用线性宽松,动画在其整个持续时间上以相同的速度进行。这通常显得很不自然和假。为了获得更自然的感觉,我们可以将缓动改变为“QuadraticInOut”,如下:
| 
 | 
这个动画师将在开始时缓慢地进行,在中间更快地进行,然后在最后再次慢慢地进行。
定义以下缓动曲线:
- 线性
- 二次
- Cubic
- Quartic
- Quintic
- 正弦
- 指数
- 循环
- 弹性
- 返回
- Bounce
它们各有三个不同的版本:[缓动] In,[缓和] Out和[缓和] InOut。
为动画师分配缓动,像这样:
| 
 | 
更改
Change在包含触发器的时候临时改变属性的值。要永久更改值,请使用设置动画。
Target属性指的是我们想要动画的属性。Value属性是动画结果的值。
- 注意:只要单元与目标的原始单元匹配,您就可以用Value指定Units。
因为设置目标属性和值的任务如此常见,所以UX具有特殊的语法。代替
| 
 | 
可以执行以下操作:
| 
 | 
Change动画可以用来动画几乎任何属性。
| 
 | 
还可以激活“宽度”,“高度”和“边距”等属性,但是因为这些属性可能会影响您的UI的整个布局,这可能最终在性能方面相当昂贵。通常有更有效的方法来做与布局交互的动画。查看LayoutAnimation和MultiLayoutPanel的一些灵感。
Cycle
“Cycle”连续地在给定频率上对两个值之间的属性进行动画处理。
<面板>
    <Translation ux:Name =“someTranslation”/>
    <WhilePressed>
        <Cycle Target =“someTranslation.X”Low =“ -  20”High =“20”Frequency =“2”/>
    </ WhilePressed>
</ Panel>
您还可以指定一个“Duration”来控制动画的长度。
Transform animators
变换动画师对元素应用变换。它们不影响布局,保证快速动画。
所有变换动画都接受可选Target属性,指示应该应用变换的元素。
Move
Move animator用于移动元素。Move不会影响布局,因此元素只会从其实际位置获得偏移量。
| 
 | 
当触发时,将沿X方向将元素移动50点。
您可能希望元素相对于其自身大小或某些其他元素大小移动。
要实现这一点,我们可以使用RelativeTo属性,例如:
| 
 | 
当触发时,将沿X方向将元素移动其自身宽度的一半。
RelativeTo可以设置为以下值:
- Local(默认):在X和/或Y方向上移动设置的点数。
- Size:移动设置的量乘以元素的大小。因此,X =“1”将元素在X方向上移动其整个宽度。
- ParentSize:与“Size”相同,但是使用元素parent size。
- PositionChange:用于响应LayoutAnimation将元素移动其父级内位置的变化量。
- WorldPositionChange:用于响应LayoutAnimation,将元素移动相对于整个显示的位置变化量。
- Keyboard:相对于键盘的大小移动元素。
RelativeNode属性允许你相对于另一个元素移动一个元素。在这种情况下,您可以使用以下RelativeTo模式:
- Size:工作方式与没有- RelativeNode时相同,但是测量- RelativeNode的大小。
- ParentSize:与“Size”相同,但是测量“RelativeNode”的父大小。
- PositionOffset:将元素移动到与- RelativeNode指定的元素相同的位置。
 偏移量被测量为两个元素之间的“ActualPosition”中的差异。
- TransformOriginOffset:像- PositionOffset,但是测量- TransformOrigin中的差异。
移动对应于在元素上添加翻译,并使用更改为其X和Y值设置动画。以下两个示例给出相同的结果。
| 
 | 
| 
 | 
Scale
Scale的工作方式与Move相同,只是它缩放元素。请注意,scale不会实际更改元素大小。这意味着UI布局的其余部分不会受到影响,并且动画保证是快速的。
您可以使用“Factor”属性沿所有轴均匀缩放元素。或者,您也可以使用Vector或X,Y和Z在每个轴上缩放。
| 
 | 
Scale可以使用相对于某些东西使用RelativeTo属性。两个选择是:
- SizeChange- 相对于由- RelativeNode属性指定的元素大小的变化。
- SizeFactor- 用相对于另一个元素的因子进行缩放,由- RelativeNode指定。“1”的系数将使其与“RelativeNode”的大小相同,而“0.5”的系数将使其为大小的一半,依此类推。
Rotate
Rotate旋转一个Element,等于添加一个Rotation并用Change来动画。
| 
 | 
使用Degrees属性可以围绕Z轴旋转元素。或者,您可以使用“DegreesX”,“DegreesY”和“DegreesZ”来围绕特定轴旋转元素。
Resize
当与LayoutAnimation一起使用时,Resize允许你设置一个元素的大小:
| 
 | 
Resize有两个选项RelativeTo:
- SizeChange- 在LayoutAnimation期间相对于大小的变化调整大小。
- Size- 相对于由- RelativeNode指定的元素的大小来调整大小。
Spin
`旋转连续旋转元素,给定一个“频率”以每秒全旋转度量。
<面板>
    <WhilePressed>
        <Spin Frequency =“2”/>
    </ WhilePressed>
</ Panel>
与Cycle一样,您也可以指定一个“Duration”来控制动画的长度。
Skew
`Skew’允许你对一个元素的倾斜变换进行动画处理。
| 
 | 
您可以使用“DegreesX”和“DegreesY”在一个轴上倾斜,或者“DegreesXY”和“XY”分别以度或弧度在两个轴上倾斜。
Attractor
“Attractor”用于给动画更自然的运动。它充当动画师和其目标之间的中介。一个“Attractor”将使用一种简单的物理模拟形式,连续地将它的目标动态化为它的“Value”。我们可以通过使吸引子的Value属性动画化来将这种行为与动画结合。
| 
 | 
关键帧:关键帧
有些情况下,我们不想简单地从点a动画到点b。对于我们想要为动画指定几个步骤的情况,我们可以使用关键帧。
| 
 | 
这个移动动画将首先动画X到10超过0.5秒,然后从10到15超过0.5秒。最后,它将从15的X变为5超过1秒。
下面是使用关键帧和更改动画制作者的示例:
<Page>
    <SolidColor ux:Name =“background”Color =“#f00”/>
    <ActivatingAnimation>
        <Change Target =“background.Color”>
            <关键帧值=“#0f0”TimeDelta =“0.25”/>
            <关键帧值=“#f00”TimeDelta =“0.25”/>
            <Keyframe Value =“#ff0”TimeDelta =“0.25”/>
            <关键帧值=“#0ff”TimeDelta =“0.25”/>
        </ Change>
    </ ActivatingAnimation>
</ Page>
这次我们使用TimeDelta代替时间。使用TimeDelta,我们可以将时间指定为相对项而不是绝对值。这意味着关键帧的顺序很重要,但它让我们推测关键帧在它们的持续时间,而不是它们在时间线上的绝对时间。
Nothing
“触发器”的所有动画共享一个公共时间轴,当最后一个动画完成时结束。在一些罕见的情况下,你可能想人为地延长时间表。这可以使用Nothing来完成。逻辑上,它是一个具有设置长度的空白动画,强制时间线的长度至少为“Nothing”的持续时间。
| 
 | 
转换
所有元素可以应用变换,以便移动,缩放或旋转。
值得一提的是,这些变换的顺序影响了它们应用于元素的顺序,因此可能导致不同的结果。
| 
 | 
| 
 | 
这两个例子有非常不同的结果。在第一种情况下,首先将面板向右移动100点,然后旋转45度。在另一种情况下,首先将面板旋转45度。正X方向现在向下45度,因此我们的面板最终向右下移动。
翻译
Translation在指定的X,Y和Z方向移动元素。以下示例显示了一个矩形,它在X方向上移动了100个点,在Y方向上移动了50个点。
| 
 | 
您可以使用以下设置“翻译”的翻译值:
- X或- Y,分别设置X和Y平移
- XY,立即设置两个轴的平移
- Z,设置Z轴的平移。
坐标默认为相对于元素的原始位置(TranslationModes.Local),但这可以使用属性RelativeTo来更改。此外,您可以使用RelativeNode相对于另一个元素进行转换。
缩放
“缩放”按照指定的因子放大或缩小元素。以下示例将使Rectangle的大小是原始大小的两倍:
| 
 | 
`缩放’可以使用:
- Factor,在所有轴上设置通用刻度
- Vector,立即设置所有三个轴的比例
- X,- Y和- Z,用于控制各个轴。
Rotation
Rotation旋转元素所指定的度数。这里是一个旋转90度的矩形的例子。
| 
 | 
您可以使用以下方式旋转元素:
- `度’,控制围绕Z轴的旋转
- DegreesX,- DegreesY,- DegreesZ,给你个人控制所有3个轴。
- EulerAngle和- EulerAngleDegrees,让你设置元素的欧拉角度,分别为弧度或度。
Shear
剪切动画可用于对元素执行剪切映射。可以使用“DegreesX”和“DegreesY”在一个轴上设置剪切,或者“度数”和“矢量”使用度数或弧度在X和Y平面中设置剪切。
Actions
触发器还可以包含动作,这些动作是在触发器时间轴中特定点触发的一次性事件。
注意,与动画相反的动作是不可逆的。这意味着如果触发器反转,则不一定可以返回到静止状态。
像animators,Actions可以有一个Delay。这指定从激活触发器到激活“动作”的秒数。然而,与’Animators’不同,它们还有一个称为AtProgress的属性,它可以设置为0和1之间的值。它具有与Delay相似的功能,但相对于完整的Duration 触发器。将AtProgress设置为0,意味着触发器激活时,触发操作。设置为0.5意味着它被点火一半,等等。
Action.AtProgress:AtProgress
Actions也有一个名为AtProgress的属性,它可以设置为0和1之间的一个值。它具有与Delay相似的功能,但相对于[Trigger](.html#Trigger)的完整[Duration](Triggers and Animators.html#Duration) 。将AtProgress`设置为0,意味着触发器激活时,触发操作。设置为0.5意味着它被点火一半,等等。
DebugAction
DebugAction允许您在激活时向Monitor /终端打印消息。
它相当于从Uno或JavaScript调用debug_log。
| 
 | 
Set
永久更改属性的值。如果您只想暂时更改它,请使用更改。当在属性上使用Set时,当包含触发器被取消激活时,该值不会被还原。在下面的示例中,我们通过设置其“SolidColor”Element的值来更改矩形的颜色。多次激活已点击触发器将不会产生任何其他效果。
| 
 | 
也可以使用它的“Target”和“Value”属性来调用集合。以下行是等效的:
| 
 | 
Callback
Callback操作用于在激活触发器时调用JavaScript函数(参见Data Binding)。
| 
 | 
GoForward
<GoForward TargetNode =“myNavigation”/>
<GoForward TargetNode =“myWebView”/>
有关导航上下文中的GoForward的更多信息,请参阅控制导航。
GoBack
<GoBack TargetNode =“myNavigation”/>
<GoBack TargetNode =“myWebView”/>
切换
Toggle用于在true和false之间切换布尔值。如果在开关内,它将切换开关的值。Toggle也可以用来激活/ deactive WhileTrue和WhileFalse触发器,如下所示:
| 
 | 
Pulse
Pulse用于暂时触发WhileTrue,WhileFalse或Timeline`。
<Button Text =“Pulse”>
    <WhileTrue ux:Name =“pulseMe”Value =“false”>
        <比例因子=“1.5”持续时间=“0.2”/>
    </ WhileTrue>
    <Clicked>
        <脉冲目标=“pulseMe”/>
    </ Clicked>
</ Button>
BringIntoView
BringIntoView操作与ScrollView控件一起使用。通过设置它的TargetNode属性,我们可以指示ScrollView去一个位置,使得Node可见。
这个例子显示如何使用BringIntoView使ScrollView通过点击按钮自动在顶部和底部之间滚动:
| 
 | 
BringToFront
UX通常是结构化的,使得在文档中更高层定义的元素在顶部绘制。
这是为了模仿流行的图形包,如Photoshop的图层行为。
使用BringToFront,可以将Target属性指定的元素置于其兄弟的前面。
- 注意:BringToFront只使元素在其父对象中最前面,而不是整个UX树。
| 
 | 
TransitionLayout
TransitionLayout操作允许您创建临时布局更改。
这可以用于进行可视布局转换,而不需要实际的布局更改。
它对自己没有明显的影响,需要与LayoutAnimation结合。
LayoutAnimation将会被这个动作触发。
<DockPanel>
    <Panel Dock =“Top”Height =“20”ux:Name =“originElement”/>
    <Button Height =“100”Dock =“Bottom”Text =“Transition!”>
        <LayoutAnimation>
            <Move X =“1”Y =“1”RelativeTo =“WorldPositionChange”Duration =“1”/>
            <Resize X =“1”Y =“1”RelativeTo =“SizeChange”Duration =“1”/>
        </ LayoutAnimation>
        <Clicked>
            <TransitionLayout From =“originElement”/>
        </ Clicked>
    </ Button>
</ DockPanel>
单击时,此示例中的按钮将执行从“originElement”(DockPanel的上边缘)的位置和大小到其实际位置和大小( DockPanel)。
NavigateToggle
切换Navigation。这当前仅在EdgeNavigation中支持,如果在其他类型的导航上使用,则不会执行任何操作。
用于EdgeNavigation,它将使用Target属性指定的EdgeNavigation.Edge集合导航到一个Panel。
Gestures
以下是对指针手势做出反应的触发器。
点击
“点击”被激活以响应点击手势。什么构成点击事件可以是平台特定的,但通常意味着指针在包含元素的边界内被按下和释放。
| 
 | 
Tapped
“Tapped”触发器与Clicked触发器非常相似。其中,点击仅意味着指针必须在元素上被按下和释放,点击意味着指针必须在按下指针之后的特定时间内被释放。
DoubleClicked
当元素在特定时间范围内点击两次时,“DoubleClicked”被激活。
DoubleTapped
与DoubleClicked一样,当元素在特定时间范围内被敲击两次时,“DoubleTapped”被激活。
WhilePressed
WhilePressed是活动的,而其包含的元素被按下,并且指针在其边界内。
| 
 | 
WhileHovering
`WhileHovering’是活动的,而指针在bounds内,如果它包含Element。
- 注意:`WhileHovering只有当设备支持悬停指针时才有价值,就像桌面机上的鼠标指针一样。对于大多数智能手机,这个触发器没有太多价值。
SwipeGesture:滑动手势
当我们想要一个元素处理滑动手势时,我们使用SwipeGesture行为。
| 
 | 
- Direction =“Right”指定这应该是一个向右滑动手势。
- Length =“100”表示滑动在指定的“方向”中的长度为100点。
- Type =“Active”表示这应该是一个双态滑动手势,在非活动/活动状态之间切换。
SwipeGesture接受以下属性:
- 方向'指定滑动的方向。 可能的值为Left- ,Up- ,Right- 和Down`。
- 可以使用Edge代替Direction,并指定可以刷新的元素的边。
 可能的值为Left,Top,Right和Bottom。
- HitSize仅适用于使用“边缘”时,并指定从边缘离开多远,我们可以开始滑动,以便识别。
- `Length’指定了我们在指定的“方向”上滑动的距离。
- LengthNode可以用来代替- Length。它引用另一个应该测量的元素来确定滑动的长度。
- Type- “活动”表示滑动应在非活动/活动状态之间切换。
- `简单’表示滑动应该调用单一的瞬间动作。
 
SwipeGesture行为本身没有影响。我们需要应用我们自己的触发器和动画师来响应手势。
在下面的小节中,我们将通过不同的触发器和动作来回应和控制SwipeGestures。
- 注意:由于您可以在同一元素上附加多个滑动手势,相关的触发器需要知道您要引用的是哪一个。
 因此,我们需要将所有滑动相关触发器的Source属性设置为它应该响应的SwipeGesture。
SwipingAnimation
SwipingAnimation执行动画以响应正在滑动的元素。
最常见的用例是将元素与指针一起移动。
<面板宽度=“100”高度=“100”背景=“#000”>
    <SwipeGesture ux:Name =“swipe”Direction =“Right”Length =“200”/>
    <SwipingAnimation Source =“swipe”>
        <Move X =“200”/>
    </ SwipingAnimation>
</ Panel>
代替使用固定长度的滑动,我们也可以从另一个元素的大小来确定它。
这是使用SwipeGesture的LengthNode属性实现的,在这种情况下也是Move的RelativeNode属性。
<Panel ux:Name =“parentContainer”Margin =“40”>
    <面板宽度=“60”高度=“60”背景=“#000”对齐=“左”>
        <SwipeGesture ux:Name =“swipe”Direction =“Right”Type =“Active”LengthNode =“parentContainer”/>
        <SwipingAnimation Source =“swipe”>
            <Move X =“1”RelativeTo =“Size”RelativeNode =“parentContainer”/>
        </ SwipingAnimation>
    </ Panel>
</ Panel>
Swiped
Swiped是一个脉冲触发器,当发生滑动时被调用。
<面板宽度=“100”高度=“100”>
    <SwipeGesture ux:Name =“swipe”Direction =“Up”Length =“50”Type =“Simple”slashb
    <Swiped Source =“swipe”>
        <比例因子=“1.5”持续时间=“0.4”DurationBack =“0.2”/>
    </ Swiped>
</ Panel>
默认情况下,“Swiped”只会在向主滑动方向滑动时(当它进入活动状态时)触发。
例如,如果SwipeGesture有方向=“左”,它只触发一个左'滑动,忽略匹配关闭滑动。
我们可以通过将How属性设置为ToActive(默认),ToInactive或ToEither’来控制这种行为。
WhileSwipeActive
WhileSwipeActive当SwipeGesture处于活动状态(当用户已经将其“打开”时)。
<面板宽度=“100”高度=“100”>
    <SwipeGesture ux:Name =“swipe”Direction =“Up”Length =“50”Type =“Simple”slashb
    <WhileSwipeActive Source =“swipe”>
        <比例因子=“1.5”持续时间=“0.4”DurationBack =“0.2”/>
    </ WhileSwipeActive>
</ Panel>
SetSwipeActive和ToggleSwipeActive
我们可以通过使用SetSwipeActive和ToggleSwipeActive动作来控制Active type SwipeGestures的状态。
<SwipeGesture ux:Name =“swipe”Direction =“Right”Length =“100”Type =“Active”/>
... ...
<StackPanel>
    <Button Text =“关闭”>
        <Clicked>
            <SetSwipeActive Target =“swipe”Value =“false”/>
        </ Clicked>
    </ Button>
    <Button Text =“Toggle”>
        <Clicked>
            <ToggleSwipeActive Target =“swipe”/>
        </ Clicked>
    </ Button>
</ StackPanel>
如果我们想绕过动画,SetSwipeActive允许我们通过设置Bypass =“true”来实现。
数据触发器
这些触发器对数据更改做出反应,无论是从数据绑定还是从控制上下文。
WhileTrue
WhileTrue是活动的,而其Value属性是True,而当它为false时是非活动的。
WhileFalse
WhileFalse是活动的,而其Value属性是False,而在它为真时是非活动的。
本机触发器
平台触发器
有时它可能需要平台特定的代码。这可以通过使用平台触发器“Android”和“iOS”来完成。
在下面的示例中,我们在Android设备上放置红色Panelif,在iOS设备上放置blue Panelif:
| 
 | 
WhileKeyboardVisible
WhileKeyboardVisible在屏幕键盘可见时处于活动状态。
TextInputActionTriggered
当用户在编辑TextInput时按下返回键时,会触发TextInputActionTriggered。
以下示例演示了如何通过从输入释放焦点,从而隐藏屏幕键盘来响应此问题。
| 
 | 
OnBackButton
当用户按下其设备上的物理或仿真后退按钮时,将触发此触发器。当按下返回按钮时,以下代码将使屏幕闪烁蓝色:
| 
 | 
OnKeyPress
当按下属性“Key”指定的键时,触发OnKeyPress。
以下示例将按下“菜单”按钮(在一些较旧的Android设备上存在)时,将屏幕蓝色闪烁。
| 
 | 
有关支持的键的完整列表,请查看Key enum列表。
本机操作
保险丝提供了一组调用操作系统特定行为的操作,例如拨打电话号码或振动设备。
Fuse.Launcher
Fuse.Launcher包允许您启动其他活动,如电子邮件,地图和网络浏览器。
- 注意:确保您将Fuse.Launcher添加到您的.unoproj文件。
LaunchUri
请操作系统启动URI。
<LaunchUri Uri =“https://www.fusetools.com”/>
URI可以是从URL到应用程序注册的自定义URI方案的任何内容。底层操作系统负责处理请求。
例如,这里是一个常见的URI方案列表,在互联网号码分配机构(IANA)注册。
LaunchEmail
启动默认电子邮件应用程序,并开始撰写邮件。
<LaunchEmail To =“contact@fusetools.com”/>
LaunchEmail接受下列属性:
- `To’ - 收件人的电子邮件地址
- CarbonCopy- 要发送副本的电子邮件地址
- “BlindCarbonCopy” - 发送盲目拷贝的电子邮件地址
- 主题电子邮件的主题
- Message- 电子邮件的正文文本
LaunchMaps
启用默认地图应用程序,给定纬度/经度对。
<LaunchMaps Latitude =“35.673813”Longitude =“ -  36.780810”/>
Call
向指定的号码发出电话呼叫。
<Call Number =“123 45 678”/>
Vibrate
振动设备达到给定的秒数。注意:iOS不会遵守任何指定的时间长度,因为这不是原生iOS API中的选项。
<振动持续时间=“0.8”/>
州组
状态组允许您使用自定义事件定义完全自定义状态。
State
一个State由一个State对象中的一组animators组成。它作为一个正常的触发器,但是由它包含StateGroup激活。
| 
 | 
StateGroup
StateGroup用于将一组states组合在一起并在它们之间切换。StateGroup有一个Active属性,用于分配哪个State当前在该组中处于活动状态。
下面是一个如何使用StateGroup来切换Rectangle在三种状态之间的颜色的例子:
| 
 | 
还可以指定“Transition”,它可以是“Exclusive”或“Parallel”。Exclusive意味着在下一个状态变为活动状态之前,每个状态必须完全禁用。
“并行”意味着当一个状态去激活时,下一个状态将变为活动状态,并且它们动画的任何属性将在它们之间内插。
用户事件
用户事件用于在应用程序的组件之间发送消息。
它们可以从UX,Uno和JavaScript发送和接收。
- 确保你也看看关于使用FuseJS从JavaScript的用户事件的文档。
UserEvent
用户事件附加到它们声明的节点,并且只有该节点及其子节点可以引发和处理事件。
<App>
    <UserEvent Name =“MyEvent”/>
    ... ...
这将创建一个名为MyEvent的事件。
通过将这个UserEvent放在App中,我们基本上把它作为一个app的事件,因为App的每个孩子都可以提出并响应这个事件。
- 注意:确保向.unoproj文件中添加“Fuse.UserEvents”。
RaiseUserEvent:从UX提高用户事件
要从UX引发user事件,请使用RaiseUserEvent操作。
<按钮>
    <Clicked>
        <RaiseUserEvent Name =“MyEvent”/>
    </ Clicked>
</ Button>
UserEventArg:传递参数
A UserEvent:user事件还可以包括可以从JavaScript或Uno读取的多个参数。
<RaiseUserEvent Name =“MyEvent”>
    <UserEventArg Name =“message”StringValue =“Hello from UX!” />
</ RaiseUserEvent>
UserEventArg接受IntValue,FloatValue,StringValue或BoolValue。
OnUserEvent:响应用户事件
要响应user事件,请使用OnUserEvent触发器。
<OnUserEvent Name =“MyEvent”>
    ... ...
</ OnUserEvent>
默认情况下,OnUserEvent只监听在其祖先节点之一中声明的事件。
如果你想监听来自任何地方的事件,将Filter属性设置为“Global”。
OnUserEvent也允许你为事件附加一个JavaScript处理程序。
<OnUserEvent Name =“MyEvent”Handler =“{myHandler}”/>
然后,处理函数可以读取与事件一起传递的arguments。
| 
 | 
Viewport triggers
这些触发器对屏幕几何形状的变化做出反应。
WhileWindowLandscape
当应用程序的视口宽度大于它的高度时,WhileWindowLandscape触发器是活动的。以下示例根据其方向更改应用程序的背景颜色:
| 
 | 
WhileWindowPortrait
当应用程序的视口高度大于或等于宽度时,WhileWindowPortrait触发器是活动的。
WhileWindowSize
WhileWindowSize触发器有三个float2属性控制它的行为:
- GreaterThan
- `LessThan
- `EqualTo
这些属性必须大于`0,0’,并且是应用程序视口必须符合的条件,以便触发器处于活动状态。以下是一个示例,如果视口大小大于某个大小,则更改应用程序的背景颜色:
| 
 | 
控制触发器
WhileEnabled
每当包含elementsIsEnabled属性设置为True时,WhileEnabled触发器是活动的。
| 
 | 
WhileDisabled
WhileDisabled触发器在其包含element的IsEnabled属性设置为`False’时处于活动状态。
聚焦触发器和操作
WhileFocused
WhileFocused触发器在其包含element被聚焦时是活动的。
WhileNotFocused
与WhileFocused相反,当它包含element的时候是not焦点。
WhileFocusWithin
WhileFocusWithin是活动的,当它的包含element的一个孩子在焦点。
GiveFocus
GiveFocus是一个动作,当激活时,它将焦点放在其包含的element中。
它还接受一个Target属性,它指定要给予焦点的元素。
ReleaseFocus
当激活时,ReleaseFocus从当前聚焦的元素中移除焦点。
WebView特定的触发器和操作
PageBeginLoading
WebView开始加载新内容时触发。
| 
 | 
WhilePageLoading
在WebView网址更改时变为活动状态,并保持活动状态,直到完成加载内容。
PageLoaded
WebView完成从当前网址加载内容后触发。
| 
 | 
Reload
Reload操作允许你告诉给定的WebView重新加载它的当前位置。
<Reload TargetNode =“myWebView”/>
LoadUrl
LoadUrl操作允许你告诉给定的WebView导航到一个位置。
<LoadUrl TargetNode =“myWebView”Url =“http://mypage.com”/>
LoadHtml
LoadHtml操作允许你为一个给定的WebView提供原始HTML,以便在触发时显示,同时还有一个基本url来设置HTML的上下文。这可以通过将操作的“Source”属性指向数据绑定的HTML字符串,或者通过包装一个HTML并将HTML放在节点体中来实现,如下所示:
| 
 | 
EvaluateJS
WebView在当前加载的Web环境中提供有限的任意JavaScript执行。这是通过<EvaluateJS />动作完成的。让我们来看一个简单的例子。
| 
 | 
注意在脚本主体中使用return语句。JavaScript评估API的实现通常像JavaScript REPL,在评估多行JS时,结果的脚本的最后一条语句成为返回值。例如,“1 + 5”在计算时是完全有效的JS,并返回期望值“6”。
这可能导致奇怪的JS,其中引用对象变成一个隐式return语句,而不允许显式返回。
| 
 | 
为了让这种感觉更好并允许返回,我们目前以一个函数的形式注入用户的JS:
| 
 | 
读取结果值
当我们评估JavaScript时,我们目前受到平台限制的关键方式:String是Android上唯一允许的返回值类型,我们的最低公分母。Android允许与API相同的API级别19,这否认我们良好的向后兼容性。现在,我们必须依靠比较古老的addJavaScriptInterface)API向后兼容。
| 
 | 
这里返回的JSON字符串然后放入一个结果对象与json键。这是为了清楚,所以你永远不会忘记,你接收的数据是一个JSON字符串,你将需要解析。
| 
 | 
注意,当然返回是可选的。如果你不返回任何从你的计算JS,表达式的返回值将只是“null”。
特殊动画
在保险丝术语中,动画是某种类型的触发器,其响应于更高级别的解释而动画化
的输入,事件和逻辑状态更改。
动画触发器被设计为解决相当具体的动画问题,否则将难以使用更简单的触发器。
另一方面,这些触发器可能有点难以理解和使用,所以请确保您在开始之前阅读文档和学习示例
太多的时间抓你的头。
LayoutAnimation
“LayoutAnimation”是响应布局更改而触发的。每当元素通过布局系统获取新布局时发生布局更改。LayoutAnimation通常与MultiLayoutPanel一起使用,用于一些非常有趣的动画。有关更多深入文档,请参阅LayoutAnimation。
AddingAnimation
每当将元素添加到视觉树中时,就会触发“AddingAnimation”。默认情况下添加动画是一种向后动画,这意味着它将从进度1动画到0。
RemovingAnimation
RemovingAnimation类似于AddingAnimation,但是当从可视树中删除一个Element时触发。
RemovingAnimation类似于AddingAnimation,但是当元素从其父元素中删除时触发。RemovingAnimation通常在指定的Duration上从0到1。
在以下示例中,当通过开关将矩形添加到视图树中时,矩形将从右侧移动其父容器的宽度一秒钟。当它被移除时,它将向左移动相同的距离。
| 
 | 
ActivatingAnimation
ActivatingAnimation允许根据Page是活动的动画。ActivatingAnimation将在页面导航到时从0进展到1。如果使用SwipeNavigate,可以观察到`ActivatingAnimation’一旦进入页面就从0开始,只要Page被激活,就保持在1,然后再次向0 Page退出。
DeactivatingAnimation
DeactivatingAnimation就像ActivatingAnimation,除了进度是相反的。这意味着触发器将在页面激活时从1进展到0,当它取消激活时,触发器从0到1。
ScrollingAnimation
ScrollingAnimation允许我们创建动画以响应正在滚动的ScrollView。通过使用“From”和“To”属性,可以在ScrollView上定义触发器被激活的间隔。
在下面的示例中,我们使用ScrollingAnimation来ScrollView在滚动时缩放。
| 
 | 
PullToReload
PullToReload允许你轻松创建一个“pull to reload”交互。
| 
 | 
通过数据绑定到IsLoading和ReloadHandler属性,我们可以响应重启正在启动。
| 
 | 
 注意:在上面的例子中,IsLoading有一个双向数据绑定到isLoading,这意味着PullToReload本身和isLoading Observable都可以改变它的值。
因为PullToReload实际上是一个ScrollingAnimation,我们可以使用它来显示一个负载指示器,当用户向下拉。
| 
 | 
WhileScrollable
WhileScrollable'用于根据是否可以滚动[ScrollView](UI Components.html#ScrollView)来动画。使用ScrollDirections`属性根据我们关心的方向过滤激活。
ScrollDirections可以取以下任意一个值:
- 全部
- 两者
- 下
- 水平
- 剩下
- 对
- 向上
- 垂直
在下面的示例中,当我们到达ScrollView的底部时,我们的背景颜色会改变:
| 
 | 
ProgressAnimation
ProgressAnimation可以与滑块一起使用,以便在元素滑动时滑动其大拇指。ProgressAnimation总是从0到1,因为滑块从最小值滑到最大值。
| 
 | 
时间轴
“时间轴”允许一个很好的方式将几个动画组合在一起,并将它们与交互逻辑分开。它可以通过在0到1之间的“TargetProgress”属性进行动画播放。
| 
 | 
RangeAdapter:Range adapter
RangeAdapter可用于调整绑定中使用的值的范围。这允许更好地控制动画,如“时间轴”和“…动画”触发器。
- Source'要修改的值。这个值总是直接更新,RangeAdapter`不会在内部存储任何值。
- SourceRangeMin映射到源的最小值
- SourceRangeMax要映射到源的最大值
- ValueRangeMin映射到值的最小值。默认值0
- ValueRangeMax要映射到的值的最大值。默认值1
- ‘Value’是要翻译的值。将此更改为使用已翻译的值更新“源”。
在以下示例中,旋转了两个面板。然而,由于其中一个面板通过“RangeAdapter”进行动画处理,它只会旋转另一个面板旋转的一半:
| 
 | 
